from rest_framework import serializers
from geopy.distance import geodesic

from alipaynfc.models import *
from merchants.models import *
from cashbonus.models import *


class NFCDeviceBountyQuestListModelSerializer(serializers.ModelSerializer):

    distance = serializers.SerializerMethodField(read_only=True)
    merchant = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = NFCDeviceBountyQuest
        fields = ('id', 'distance', 'merchant', 'task_id', 'amount', 'longitude', 'latitude')

    def get_distance(self, obj):
        longitude = self.context.get('longitude', None)
        latitude = self.context.get('latitude', None)
        if longitude and latitude:
            try:
                distance = geodesic((obj.latitude, obj.longitude), (latitude, longitude)).m
                if distance > 1000:
                    return f'{round(distance/1000, 1)} km'
                else:
                    return f'{int(distance)} m'
            except:
                return ''
        else:
            return ''

    def get_merchant(self, obj):
        data = {}
        try:
            merchant = obj.merchant
            data['merchant_name'] = merchant.name
            data['merchant_short_name'] = merchant.short_name
            data['address'] = merchant.store_address
        except:
            pass
        return data


class NFCDeviceBountyQuestRetrieveModelSerializer(serializers.ModelSerializer):

    distance = serializers.SerializerMethodField(read_only=True)
    merchant = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = NFCDeviceBountyQuest
        fields = ('id', 'distance', 'merchant', 'task_id', 'amount', 'longitude', 'latitude')

    def get_distance(self, obj):
        longitude = self.context.get('longitude', None)
        latitude = self.context.get('latitude', None)
        if longitude and latitude:
            try:
                distance = geodesic((obj.latitude, obj.longitude), (latitude, longitude)).m
                if distance > 1000:
                    return f'{round(distance/1000, 1)} km'
                else:
                    return f'{int(distance)} m'
            except:
                return ''
        else:
            return ''

    def get_merchant(self, obj):
        data = {}
        try:
            picture_list = []
            merchant = obj.merchant
            data['merchant_name'] = merchant.name
            data['merchant_short_name'] = merchant.short_name
            data['address'] = merchant.store_address
            merchant_image_set = MerchantImage.objects.filter(merchant_id=obj.merchant_id)
            for merchant_image in merchant_image_set:
                picture_list.append(merchant_image.image.url)
            data['picture_list'] = picture_list
        except:
            pass
        return data


class NFCDeviceBountyQuestScheduleListModelSerializer(serializers.ModelSerializer):

    amount = serializers.SerializerMethodField(read_only=True)
    task_id = serializers.SerializerMethodField(read_only=True)
    merchant = serializers.SerializerMethodField(read_only=True)
    longitude = serializers.SerializerMethodField(read_only=True)
    latitude = serializers.SerializerMethodField(read_only=True)
    quest_status_str = serializers.CharField(source='get_quest_status_display', read_only=True)
    distance = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = NFCDeviceBountyQuestSchedule
        fields = ('id', 'amount', 'quest_status', 'quest_status_str', 'merchant', 'task_id', 'longitude', 'latitude', 'distance')

    def get_distance(self, obj):
        longitude = self.context.get('longitude', None)
        latitude = self.context.get('latitude', None)
        if longitude and latitude:
            try:
                distance = geodesic((obj.quest.latitude, obj.quest.longitude), (latitude, longitude)).m
                if distance > 1000:
                    return f'{round(distance/1000, 1)} km'
                else:
                    return f'{int(distance)} m'
            except:
                return ''
        else:
            return ''

    def get_longitude(self, obj):
        try:
            return obj.quest.longitude
        except:
            return ''

    def get_latitude(self, obj):
        try:
            return obj.quest.latitude
        except:
            return ''

    def get_amount(self, obj):
        try:
            return obj.quest.amount
        except:
            return '0'

    def get_merchant(self, obj):
        data = {}
        try:
            merchant = obj.quest.merchant
            data['merchant_name'] = merchant.name
            data['merchant_short_name'] = merchant.short_name
            data['address'] = merchant.store_address
        except:
            pass
        return data

    def get_task_id(self, obj):
        try:
            return obj.quest.task_id
        except:
            return ''


class NFCDeviceBountyQuestScheduleRetrieveModelSerializer(serializers.ModelSerializer):

    amount = serializers.SerializerMethodField(read_only=True)
    task_id = serializers.SerializerMethodField(read_only=True)
    merchant = serializers.SerializerMethodField(read_only=True)
    quest_status_str = serializers.CharField(source='get_quest_status_display', read_only=True)
    appeal_status_str = serializers.CharField(source='get_appeal_status_display', read_only=True)
    distance = serializers.SerializerMethodField(read_only=True)
    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    expired_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    cancel_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    appeal_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    handle_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    success_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    assist_set = serializers.SerializerMethodField(read_only=True)
    longitude = serializers.SerializerMethodField(read_only=True)
    latitude = serializers.SerializerMethodField(read_only=True)
    award = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = NFCDeviceBountyQuestSchedule
        fields = ('id', 'amount', 'quest_status', 'quest_status_str', 'merchant', 'task_id', 'distance', 'appeal_explain', 'assist_set',
                  'create_time', 'expired_time', 'cancel_time', 'appeal_time', 'longitude', 'latitude', 'handle_time', 'handle_explain',
                  'award', 'appeal_status', 'appeal_status_str', 'success_time')

    def get_award(self, obj):
        data = {}
        data['id'] = ''
        data['state'] = ''
        data['received_time'] = ''
        data['return_msg'] = ''
        try:
            award = obj.award
            if award:
                data['id'] = award.id
                data['state'] = award.state
                data['return_msg'] = award.return_msg
                data['received_time'] = award.received_time.strftime("%Y-%m-%d %H:%M:%S")
        except:
            pass
        return data

    def get_longitude(self, obj):
        try:
            return obj.quest.longitude
        except:
            return ''

    def get_latitude(self, obj):
        try:
            return obj.quest.latitude
        except:
            return ''

    def get_amount(self, obj):
        try:
            return obj.quest.amount
        except:
            return '0'

    def get_merchant(self, obj):
        data = {}
        try:
            picture_list = []
            merchant = obj.quest.merchant
            data['merchant_name'] = merchant.name
            data['merchant_short_name'] = merchant.short_name
            data['address'] = merchant.store_address
            merchant_image_set = MerchantImage.objects.filter(merchant_id=obj.quest.merchant_id)
            for merchant_image in merchant_image_set:
                picture_list.append(merchant_image.image.url)
            data['picture_list'] = picture_list
        except:
            pass
        return data

    def get_task_id(self, obj):
        try:
            return obj.quest.task_id
        except:
            return ''

    def get_distance(self, obj):
        longitude = self.context.get('longitude', None)
        latitude = self.context.get('latitude', None)
        if longitude and latitude:
            try:
                quest = obj.quest
                distance = geodesic((quest.latitude, quest.longitude), (latitude, longitude)).m
                if distance > 1000:
                    return f'{round(distance/1000, 1)} km'
                else:
                    return f'{int(distance)} m'
            except:
                return ''
        else:
            return ''

    def get_assist_set(self, obj):
        data = []
        try:
            queryset = NFCDeviceBountyQuestScheduleAppealAssist.objects.filter(schedule_id=obj.id)
            for query in queryset:
                data.append(query.picture.url)
        except:
            pass
        return data



